package dbfactroy

import (
	"fmt"
	"gitee.com/ichub/goconfig/common/base/baseutils/fileutils"
	"gitee.com/ichub/gofactroy/common/ichubbase"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"strings"
)

type FileFactroy struct {
}

var InstFileFactroy FileFactroy

var (
	Gendir, Gendir_PBTool, Gendir_PBTool_BIN, GendirTest string

	Gendir_model, Gendir_dto                string
	Gendir_dao, Gendir_interface            string
	Gendir_service, Gendir_esservice        string
	Gendir_proto, Gendir_grpc               string
	Gendir_controller, Gendir_rpcController string

	Gendir_controller_test, Gendir_dao_test    string
	Gendir_service_test, Gendir_esservice_test string
	Gendirs, Gendirs_test                      []string
)

func InitPathMysql() {
	initDir("gendir-mysql/")
	initTest()

}

func init() {
	initDir("gendir-pg/")
	initTest()
}

func initTest() {
	workDir := fileutils.FindRootDir() + "/data"
	GendirTest = workDir + "/factroy/gendir-test/" + ichubbase.MODULE_MAP[ichubbase.APP].ModelTestPath

	Gendir_controller_test = GendirTest + "/web"
	Gendir_dao_test = GendirTest + "/dao"
	Gendir_service_test = GendirTest + "/service"
	Gendir_esservice_test = GendirTest + "/esservice"

	Gendirs_test = append(Gendirs_test, Gendir_dao_test)
	Gendirs_test = append(Gendirs_test, Gendir_service_test)
	Gendirs_test = append(Gendirs_test, Gendir_esservice_test)

	os.MkdirAll(Gendir, os.ModePerm)
	for _, v := range Gendirs_test {
		os.MkdirAll(v, os.ModePerm)
	}
}

func initDir(dbtype string) {
	workDir := fileutils.FindRootDir() + "/data"

	Gendir = workDir + "/factroy/" + dbtype + ichubbase.MODULE_MAP[ichubbase.APP].ModelPath
	Gendir_PBTool_BIN = workDir + "/bin"
	Gendir_PBTool = workDir + "/bin/proto"

	Gendir_model = Gendir + "/model"
	Gendir_dto = Gendir + "/dto"

	Gendir_dao = Gendir + "/dao"

	Gendir_interface = Gendir + "/inter"
	Gendir_service = Gendir + "/service"
	Gendir_esservice = Gendir + "/esservice"

	Gendir_proto = Gendir + "/proto"
	Gendir_grpc = Gendir + "/grpc"
	Gendir_controller = Gendir + "/web"
	Gendir_rpcController = Gendir + "/grpc.web"

	Gendirs = append(Gendirs, Gendir)
	Gendirs = append(Gendirs, Gendir_proto)
	Gendirs = append(Gendirs, Gendir_model)
	Gendirs = append(Gendirs, Gendir_dto)
	Gendirs = append(Gendirs, Gendir_dao)
	Gendirs = append(Gendirs, Gendir_service)
	Gendirs = append(Gendirs, Gendir_esservice)

	// Gendirs = append(Gendirs, Gendir_grpc)
	Gendirs = append(Gendirs, Gendir_controller)

}

func (this *FileFactroy) InfoPath() {
	fmt.Println("你产生的代码路径在：" + Gendir)
	log.Println("你产生的代码路径在：" + Gendir)
}

func RmDirs() {
	for _, v := range Gendirs {
		os.RemoveAll(v)
	}

}

func CreateDirs() {
	os.MkdirAll(Gendir, os.ModePerm)

}

func ReCreateDirs() {
	RmDirs()
	CreateDirs()
}

func (this *FileFactroy) PathExists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return false, err
}

func (this *FileFactroy) TransDir(path string, base string) string {
	base = strings.ToLower(base)
	path = strings.ReplaceAll(path, Gendir, Gendir+"/"+base)

	os.MkdirAll(Gendir+"/"+base, os.ModeDir)
	os.MkdirAll(path, os.ModeDir)
	return path
}

func (this *FileFactroy) WriteFileModule(dir string, filename string, cms string) {

	cms = strings.ReplaceAll(cms, ichubbase.MODULE_NAME_SHOP, ichubbase.MODULE_MAP[ichubbase.APP].ModelPath)

	this.WriteFile(dir, filename, cms)

}

func (this *FileFactroy) WriteFileModuleRpc(dir, filename, cms string) {

	cms = strings.ReplaceAll(cms, ichubbase.MODULE_NAME_SHOP, ichubbase.MODULE_MAP[ichubbase.APP].ModelPath)
	cms = strings.ReplaceAll(cms, ichubbase.MODULE_NAME_NOW, ichubbase.MODULE_NAME_NEW)

	os.MkdirAll(dir, os.ModeDir)

	this.WriteFile(dir, filename, cms)

}

func (this *FileFactroy) WriteFile(dir string, filename string, cms string) {
	ise, _ := this.PathExists(dir)
	if !ise {
		os.MkdirAll(dir, os.ModePerm)
	}
	ise, _ = this.PathExists(dir)
	if !ise {
		panic(fmt.Sprintf("dir %s not exists!", dir))
	}
	f, err := os.Create(dir + "/" + filename)
	defer f.Close()
	fmt.Println(dir + "/" + filename)

	if err != nil {
		fmt.Println(err)
		return
	}
	f.WriteString(cms)
}

func (this *FileFactroy) ReadFile(filename string) []byte {

	f, err := os.Open(filename)
	if err != nil {
		panic(err)
	}
	defer f.Close()

	b, err := ioutil.ReadAll(f)
	if err != nil {
		fmt.Println(err.Error())
	}
	return b
}
func (this *FileFactroy) ReadTemplate(f string) []byte {
	dir := fileutils.FindRootDir() + "/config/template/"

	fs := strings.Split(f, "/")
	var l = len(fs)
	var ff = fs[l-1]
	if strings.Contains(f, "/test") {
		ff = f
	}
	return this.ReadFile(dir + ff)

}

func (this *FileFactroy) ReadTemplateDto() []byte {
	dir, _ := os.Getwd()
	return this.ReadTemplate(dir + "/factroy/template/Dto.template")

}

func (this *FileFactroy) ReadTemplateModel() []byte {
	dir, _ := os.Getwd()
	return this.ReadTemplate(dir + "/factroy/template/Model.template")

}

func (this *FileFactroy) ReadTemplateDAO() []byte {
	dir, _ := os.Getwd()
	return this.ReadTemplate(dir + "/factroy/template/Dao.template")

}
func (this *FileFactroy) ReadTemplateRpc() []byte {
	dir, _ := os.Getwd()
	return this.ReadTemplate(dir + "/factroy/template/Rpc.template")

}

func (this *FileFactroy) ReadTemplateProto() []byte {
	dir, _ := os.Getwd()
	return this.ReadTemplate(dir + "/factroy/template/Rpc.proto.template")

}

func (this *FileFactroy) ReadTemplateServiceInterface() []byte {
	dir, _ := os.Getwd()
	return this.ReadTemplate(dir + "/factroy/template/Interface.template")

}
func (this *FileFactroy) ReadTemplateESService() []byte {
	dir, _ := os.Getwd()
	return this.ReadTemplate(dir + "/factroy/template/ESService.template")

}

func (this *FileFactroy) ReadTemplateService() []byte {
	dir, _ := os.Getwd()
	return this.ReadTemplate(dir + "/factroy/template/Service.template")

}

func (this *FileFactroy) ReadTemplateController() []byte {
	dir, _ := os.Getwd()
	return this.ReadTemplate(dir + "/factroy/template/Controller.template")

}

func (this *FileFactroy) ReadTemplateRpcController() []byte {
	dir, _ := os.Getwd()
	return this.ReadTemplate(dir + "/factroy/template/Rpc.Controller.template")

}

func (this *FileFactroy) ReadTestTemplateMqESSrv() []byte {
	dir, _ := os.Getwd()
	return this.ReadTemplate(dir + "/factroy/template/multiquery/test/Srv_test.go.template")

}
func (this *FileFactroy) ReadTestTemplateMqSrv() []byte {
	dir, _ := os.Getwd()
	return this.ReadTemplate(dir + "/factroy/template/multiquery/test/Srv_test.go.template")

}
func (this *FileFactroy) ReadTemplateMqProto() []byte {
	dir, _ := os.Getwd()
	return this.ReadTemplate(dir + "/factroy/template/multiquery/Rpc.proto.template")

}

func (this *FileFactroy) ReadTestTemplateESSrv() []byte {

	return this.ReadTemplate("/test/Srv_test.go.template")

}
func (this *FileFactroy) ReadTestTemplateController() []byte {
	return this.ReadTemplate("/test/Controller_test.go.template")

}

func (this *FileFactroy) ReadTestTemplateSrv() []byte {

	return this.ReadTemplate("/test/Srv_test.go.template")

}

func (this *FileFactroy) ReadTestTemplateDAO() []byte {

	return this.ReadTemplate("/test/Dao_test.go.template")

}

func (this *FileFactroy) ReadTemplateMqDAO() []byte {
	dir, _ := os.Getwd()
	return this.ReadTemplate(dir + "/factroy/template/multiquery/Dao.template")

}

func (this *FileFactroy) ReadTemplateMqDTO() []byte {
	dir, _ := os.Getwd()
	return this.ReadTemplate(dir + "/factroy/template/multiquery/Dto.template")

}

func (this *FileFactroy) ReadTemplateMqService() []byte {
	dir, _ := os.Getwd()
	return this.ReadTemplate(dir + "/factroy/template/multiquery/Service.template")

}

func (this *FileFactroy) ExecPb() {
	cmd := exec.Command("pb")

	if err := cmd.Start(); err != nil { // 运行命令

		log.Fatal(err)

	}

}
